using System;
using System.Collections.Generic;
using UnityEngine;
using Voodoo.Sauce.Internal.DebugScreen;
using Voodoo.Sauce.Tools.AccessButton;

namespace Voodoo.Sauce.Debugger
{
	[RequireComponent(typeof(Canvas))]
	public class DebuggerCanvas : MonoBehaviour
	{
		[SerializeField]
		private DebuggerCanvasData _data;

		[SerializeField]
		private HomeDebugScreen _homePrefab;

		[SerializeField]
		private DebuggerHeader _header;

		[SerializeField]
		private Transform _bodyRoot;

		[SerializeField]
		private Transform _hiddenRoot;

		[SerializeField]
		private DebuggerPopupScreen _popupScreen;

		[SerializeField]
		private CustomDebuggerScreen _customDebuggerScreen;

		private Canvas _canvas;

		private Stack<Screen> _screenQueue = new Stack<Screen>();

		public bool IsOpened => _canvas.enabled;

		public bool IsHome => _screenQueue.Count <= 1;

		private void Awake()
		{
			UnityEngine.Object.DontDestroyOnLoad(base.gameObject);
			_canvas = GetComponent<Canvas>();
			List<Screen> list = new List<Screen>();
			Screen[] screenPrefabs = _data.screenPrefabs;
			for (int i = 0; i < screenPrefabs.Length; i++)
			{
				Screen screen = UnityEngine.Object.Instantiate(screenPrefabs[i], _bodyRoot);
				SetScreenVisibility(screen, visible: false);
				list.Add(screen);
			}
			foreach (CustomDebugger item in DebugCustomUtility.GetAllCustomDebugger())
			{
				CustomDebuggerScreen customDebuggerScreen = UnityEngine.Object.Instantiate(_customDebuggerScreen, _bodyRoot);
				customDebuggerScreen.Initialize(item);
				SetScreenVisibility(customDebuggerScreen, visible: false);
				list.Add(customDebuggerScreen);
			}
			HomeDebugScreen homeDebugScreen = UnityEngine.Object.Instantiate(_homePrefab, _bodyRoot);
			homeDebugScreen.Initialize(list);
			Push(homeDebugScreen);
			Close();
		}

		public void Open()
		{
			AccessProcess.SetTrustedUser(isTrusted: true);
			AccessProcess.SetAccess(hasAccess: true);
			_canvas.enabled = true;
			_bodyRoot.gameObject.SetActive(value: true);
		}

		public void Push(Screen screen)
		{
			if (_screenQueue.Count > 0)
			{
				Screen screen2 = _screenQueue.Peek();
				if (screen2.mainSubScreen == null)
				{
					SetScreenVisibility(screen2, visible: false);
				}
			}
			SetScreenVisibility(screen, visible: true);
			UpdateHeader(screen);
			_screenQueue.Push(screen);
			if ((bool)screen.mainSubScreen)
			{
				Push(screen.mainSubScreen);
			}
			screen.OnScreenShow();
		}

		public Screen Pop()
		{
			if (IsHome)
			{
				Debug.LogError("Trying to dequeue when screen queue is only left one item should not be done.");
				return null;
			}
			Screen screen = _screenQueue.Pop();
			SetScreenVisibility(screen, visible: false);
			Screen screen2 = _screenQueue.Peek();
			if (screen2.mainSubScreen == screen)
			{
				return Pop();
			}
			SetScreenVisibility(screen2, visible: true);
			UpdateHeader(screen2);
			return screen;
		}

		public void Toggle(Screen screen)
		{
			if (_screenQueue.Peek() == screen)
			{
				Pop();
			}
			else
			{
				Push(screen);
			}
		}

		private void SetScreenVisibility(Screen screen, bool visible)
		{
			if (!visible)
			{
				screen.OnScreenHide();
			}
			screen.gameObject.SetActive(visible);
			Transform parent = (visible ? _bodyRoot : _hiddenRoot);
			screen.transform.SetParent(parent, worldPositionStays: true);
		}

		public void UpdateHeader(Screen screen)
		{
			_header.UpdateTarget(screen);
		}

		public void Close()
		{
			_canvas.enabled = false;
			_bodyRoot.gameObject.SetActive(value: false);
		}

		public void ShowPopup(DebuggerPopupConfig config)
		{
			Action closeCallback = null;
			if (!IsOpened)
			{
				_header.gameObject.SetActive(value: false);
				_canvas.enabled = true;
				closeCallback = delegate
				{
					_header.gameObject.SetActive(value: true);
					_canvas.enabled = false;
				};
			}
			_popupScreen.Show(config, closeCallback);
		}
	}
}
